package com.platform.common.config.shiro;

import com.platform.common.redis.RedisUtil;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Shiro Session DAO类
 * 
 * @author LiangMingHui
 *
 */
public class ShiroSessionDAO extends AbstractSessionDAO {

	private static final Logger logger = LoggerFactory.getLogger(ShiroSessionDAO.class);

	private static final int SESSION_TIMEOUT = 7200;

	private static final String KEY_PREFIX = "SHIRO_SESSION:";

	private String getSessionKey(Serializable sessionId) {
		return new StringBuilder(KEY_PREFIX).append(sessionId).toString();
	}

	@Override
	public void delete(Session session) {
		if (session == null || session.getId() == null) {
			logger.error("session or session id is null");
			return;
		}
		RedisUtil.getInstance().del(this.getSessionKey(session.getId()));
	}

	@Override
	public void update(Session session) throws UnknownSessionException {
		this.saveSession(session);
	}

	private void saveSession(Session session) throws UnknownSessionException {
		if (session == null || session.getId() == null) {
			logger.error("session or session id is null");
			return;
		}
		session.setTimeout(SESSION_TIMEOUT * 1000); // 半小时
		RedisUtil.getInstance().setObject(this.getSessionKey(session.getId()), session, SESSION_TIMEOUT);
	}

	@Override
	protected Serializable doCreate(Session session) {
		Serializable sessionId = this.generateSessionId(session);
		this.assignSessionId(session, sessionId);
		this.saveSession(session);
		return sessionId;
	}

	@Override
	protected Session doReadSession(Serializable sessionId) {
		if (sessionId == null) {
			logger.error("session id is null");
			return null;
		}

		Session session = (Session) RedisUtil.getInstance().getObject(this.getSessionKey(sessionId));
		if (session != null) {
			RedisUtil.getInstance().setObject(this.getSessionKey(sessionId), session, SESSION_TIMEOUT);
			session.setTimeout(SESSION_TIMEOUT * 1000); // 半小时
		}
		return session;
	}

	@Override
	public Collection<Session> getActiveSessions() {
		List<Session> listSession = new ArrayList<Session>();
		List<Object> listSessionObj = RedisUtil.getInstance().keysObject(KEY_PREFIX + "*");
		for (Object obj : listSessionObj) {
			listSession.add((Session) obj);
		}
		return listSession;
	}
}